<?php
/*
 * 此文件用于验证短信服务API接口，供开发时参考
 * 执行验证前请确保文件为utf-8编码，并替换相应参数为您自己的信息，并取消相关调用的注释
 * 建议验证前先执行Test.php验证PHP环境
 *
 * 2017/11/30
 */

namespace alisms;

use think\Db;

class AlismsHandler{
    private $accessKeyId = null;
    private $accessKeySecret = null;
    public function __construct(){
        $this->accessKeyId = "LTAIfh7Vajfs67pj";
        $this->accessKeySecret = "MPLQOgG7c9dJVUhJTAljiQxzcecCbp";
    }


    /**
     * 发送短信
     */
    public function sendSingleSms(String $phone,Array $param,$template_id=7) {
        $check = $this->beforeSendCheck($phone);
        if(!$check){
            return ['status'=>0,'msg'=>'发送间隔不能少于60秒'];
        }

        $params = [];

        $template_list = array(
            1 => 'SMS_108405071', //验证码${code}，您正在尝试变更重要信息，请妥善保管账户信息。
            2 => 'SMS_108405072', //验证码${code}，您正在尝试修改登录密码，请妥善保管账户信息。
            3 => 'SMS_108405073', //验证码${code}，您正在注册成为新用户，感谢您的支持！
            4 => 'SMS_108405074', //验证码${code}，您正尝试异地登录，若非本人操作，请勿泄露。
            5 => 'SMS_108405075', //验证码${code}，您正在登录，若非本人操作，请勿泄露
            7 => 'SMS_108405077', //验证码${code}，您正在进行身份验证，打死不要告诉别人哦！
        );
        // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息


        // fixme 必填: 短信接收号码
        $params["PhoneNumbers"] = $phone;

        // fixme 必填: 短信签名，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $params["SignName"] = "鸭梨科技";

        // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
        $params["TemplateCode"] = $template_list[$template_id];

        // fixme 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
        $params['TemplateParam'] = Array (
            "code" => $param['code']
        );

        // fixme 可选: 设置发送短信流水号
        // $params['OutId'] = "12345";

        // fixme 可选: 上行短信扩展码, 扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段
        // $params['SmsUpExtendCode'] = "1234567";

        // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
        if(!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
        }
        $content = $this->parseTemplate($template_id,$param);
        $res = $this->doRequest($params,"SendSms");

        if($res !== false){
            $res = json_decode(json_encode($res),true);
        }else{
            $return = ['status'=>0,'msg'=>'暂无法发送短信'];
        }
        if($res['Code']=='OK'){
            $return = ['status'=>1,'msg'=>'发送成功'];
        }else{
            $return = ['status'=>0,'msg'=>$res['Message']];
        }

        $content = $this->parseTemplate($template_id,$param);

        $save = [
            'web_id'  => !empty(config('web_id'))?config('web_id'):0,
            'lang_id' => 1,
            'phone'   => $phone,
            'content' => $content,
            'status'  => $return['status'],
            'remark'  => $return['msg']??'未知错误',
            'addtime' => request()->time(),
            'sendtime'=> request()->time(),
        ];
        model('Common/ConfigSet')->set_sms_log('add',1, $save);
        return $return;
    }

    public function sendBatchSms($template_id,$phone,$param) {

        $params = array ();

        // *** 需用户填写部分 ***

        // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息
        $accessKeyId = "your access key id";
        $accessKeySecret = "your access key secret";

        // fixme 必填: 待发送手机号。支持JSON格式的批量调用，批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
        $params["PhoneNumberJson"] = array(
            "1500000000",
            "1500000001",
        );

        // fixme 必填: 短信签名，支持不同的号码发送不同的短信签名，每个签名都应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $params["SignNameJson"] = array(
            "云通信",
            "云通信2",
        );

        // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
        $params["TemplateCode"] = "SMS_1000000";

        // fixme 必填: 模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
        $params["TemplateParamJson"] = array(
            array(
                "name" => "Tom",
                "code" => "123",
            ),
            array(
                "name" => "Jack",
                "code" => "456",
            ),
        );

        // todo 可选: 上行短信扩展码, 扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段
        // $params["SmsUpExtendCodeJson"] = json_encode(array("90997","90998"));


        // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
        $params["TemplateParamJson"]  = json_encode($params["TemplateParamJson"], JSON_UNESCAPED_UNICODE);
        $params["SignNameJson"] = json_encode($params["SignNameJson"], JSON_UNESCAPED_UNICODE);
        $params["PhoneNumberJson"] = json_encode($params["PhoneNumberJson"], JSON_UNESCAPED_UNICODE);

        if(!empty($params["SmsUpExtendCodeJson"] && is_array($params["SmsUpExtendCodeJson"]))) {
            $params["SmsUpExtendCodeJson"] = json_encode($params["SmsUpExtendCodeJson"], JSON_UNESCAPED_UNICODE);
        }

        // 此处可能会抛出异常，注意catch
        $content = $this->doRequest($params,"SendBatchSms");

        return $content;
    }

    /**
     * 短信发送记录查询
    */
    public function querySendDetails() {

        $params = [];

        // *** 需用户填写部分 ***

        // fixme 必填: 短信接收号码
        $params["PhoneNumber"] = "17000000000";

        // fixme 必填: 短信发送日期，格式Ymd，支持近30天记录查询
        $params["SendDate"] = "20170710";

        // fixme 必填: 分页大小
        $params["PageSize"] = 10;

        // fixme 必填: 当前页码
        $params["CurrentPage"] = 1;

        // fixme 可选: 设置发送短信流水号
        $params["BizId"] = "yourBizId";

        $content = $this->doRequest($params,"QuerySendDetails");
    }

    private function doRequest($params,$action){
        // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
        $helper = new SignatureHelper();
        // 此处可能会抛出异常，注意catch
        $content = $helper->request(
            $this->accessKeyId,
            $this->accessKeySecret,
            "dysmsapi.aliyuncs.com",
            array_merge($params, array(
                "RegionId" => "cn-hangzhou",
                "Action" => $action,
                "Version" => "2017-05-25",
            ))
        );
        return $content;
    }

    private function parseTemplate($template_id,$param){
        $template_list = [
            1 => '验证码${code}，您正在尝试变更重要信息，请妥善保管账户信息。',
            2 => '验证码${code}，您正在尝试修改登录密码，请妥善保管账户信息。',
            3 => '验证码${code}，您正在注册成为新用户，感谢您的支持！',
            4 => '验证码${code}，您正尝试异地登录，若非本人操作，请勿泄露。',
            5 => '验证码${code}，您正在登录，若非本人操作，请勿泄露!',
            7 => '验证码${code}，您正在进行身份验证，打死不要告诉别人哦！',
        ];
        $content = $template_list[$template_id];
        foreach ($param as $key => $value) {
            $content = str_replace('${'.$key.'}',$value,$content);
        }
        return $content;
    }

    private function beforeSendCheck($phone,$limit_time=60){
        $valid_addtime = request()->time()-$limit_time;
        return Db::connect(config('database.db_config1'))->name('SmsLog')->where(['phone'=>$phone,'addtime'=>['gt',$valid_addtime]])->count()?false:true;
    }
}
